fix(markdown): add backslash-escape handling in parser and serializer#7898
Conversation
✅ Deploy Preview for tiptap-embed ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
🦋 Changeset detectedLatest commit: 4b9bfd3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 72 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Pull request overview
This PR fixes markdown backslash-escape handling in @tiptap/markdown so escaped punctuation is preserved on parse and markdown-significant characters in plain text are escaped on serialize, improving round-trip stability and preventing accidental formatting.
Changes:
- Parse marked.js
escapetokens as literal text nodes (so\*,\_,\\, etc. are not dropped). - Merge adjacent text nodes with identical marks after inline parsing to keep JSON output compact/consistent.
- Escape markdown-significant characters during serialization for non-code text nodes to avoid unintended formatting on re-parse.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/markdown/src/MarkdownManager.ts | Adds parsing support for escape tokens, merges adjacent compatible text nodes, and escapes markdown syntax during text serialization (outside code contexts). |
| packages/markdown/tests/conversion.spec.ts | Adds regression coverage for parsing escaped characters, serialization escaping, round-trip stability, and code-context exemptions. |
| .changeset/fix-markdown-escape-handling.md | Publishes the user-facing fix as a patch changeset for @tiptap/markdown. |
alexvcasillas
left a comment
There was a problem hiding this comment.
Looks good 👍🏻 Just dropped a small question about the JSON.stringify equal comparison
Replace JSON.stringify-based mark comparison in MarkdownManager with marksEqual. Add unit tests for marksEqual covering key order, missing attrs, length and type differences
Export attrsEqual and marksEqual from @tiptap/core utilities. Add unit tests for both, remove duplicated implementations in the markdown package, and add a changeset
Changes Overview
Fix backslash-escape handling in
@tiptap/markdown. Backslash-escaped markdown characters (e.g.\*,\_,\\) were silently dropped during parsing, and markdown-significant characters in text nodes were not escaped during serialization.Implementation Approach
Two-pronged fix in
MarkdownManager.ts:Parsing (Markdown → ProseMirror): Added handling for marked.js
escapetokens in bothparseInlineTokensandparseFallbackToken. Theescapetoken'stextproperty (the escaped character) is used directly to create a text node. Adjacent text nodes are merged to match ProseMirror's expectations.Serialization (ProseMirror → Markdown): Added
escapeMarkdownSyntax()method that backslash-escapes markdown-significant characters (\,`,*,_,[,],~) in text nodes during serialization. This runs after HTML entity encoding and respects the existingisInsideCodeguard so code blocks/marks remain untouched.The solution is generic — it works with all extensions since escapes are handled at the manager level, not per-extension.
Testing Done
Verification Steps
@tiptap/markdownextension in the demo\*text\*→ should display literal*text*, not italic\\→ should display a single backslash\_text\_→ should display literal_text_, not italicAdditional Notes
N/A
AI Usage
Checklist
Related Issues
Closes #7258